function forge_rsa_help() {
    this.conf = {
        bit_size: 1024,
        publicKey: "",
        privateKey: "",
        delimiter: "",
    };
    this._set = function (name, val) {
        if (y_string(name)) {
            if (in_array(name, ["bit_size", "publicKey", "privateKey", "delimiter"], true)) {
                this.conf[name] = val;
            } else {
                !is_function(this[name]) && in_array(name, ["conf", "forge", "pki", "rsa", "util"]) && (this[name] = val);
            }
        }
        return this;
    };
    //设置RSA密钥长度
    this.bitSize = function (val) {
        return this._set("bit_size", val);
    };
    //设置公钥字符串
    this.pubKey = function (val) {
        return this._set("publicKey", val);
    };
    //设置私钥字符串
    this.priKey = function (val) {
        return this._set("privateKey", val);
    };
    /**
     * 设置分隔符，使用分隔符把分段加密的密文分割开，然后发送，可以不设置
     * @param val
     * @returns {*}
     */
    this.delimiter = function (val) {
        return this._set("delimiter", val);
    };
    /**
     * 公钥加密，需要提前设置 bit_size,publicKey,delimiter（可以不设置）
     * @param plaintext
     * @param is_url
     * @returns {*}
     */
    this.pubKeyEncrypt = function (plaintext, is_url) {
        var c = this.conf;
        return this.publicEncrypt(c.publicKey, plaintext, c.bit_size, is_url, c.delimiter);
    };
    /**
     * 私钥解密，需要提前设置 bit_size,privateKey,delimiter（可以不设置）
     * @param cipherText
     * @param is_url
     * @returns {*}
     */
    this.priKeyDecrypt = function (cipherText, is_url) {
        var c = this.conf;
        return this.privateDecrypt(c.privateKey, cipherText, c.bit_size, is_url, c.delimiter);
    };
    return this;
}

forge_rsa_help.prototype = {
    forge: forge ? forge : undefined,
    pki: forge && forge.pki ? forge.pki : undefined,
    rsa: forge && forge.rsa ? forge.rsa : undefined,
    util: forge && forge.util ? forge.util : undefined,
    /**
     * 公钥加密（长字符串加密）
     * @param {string} publicKey 公钥字符串
     * @param {string} plaintext 明文
     * @param {number} bit_size 密钥长度
     * @param {boolean} is_url 是否使用url传递
     * @param {string} delimiter 分隔符
     */
    publicEncrypt: function (publicKey, plaintext, bit_size, is_url, delimiter) {
        var cipherText = [], pki = forge.pki, util = forge.util, enStr;
        delimiter || (delimiter = "");
        (delimiter && /^[A-Za-z0-9_+\-\/]+$/.test(delimiter)) && (delimiter = ".");
        var pubKey = pki.publicKeyFromPem(publicKey);
        //var buffer = forge.util.createBuffer(plaintext, 'utf8');
        //var bytes = buffer.getBytes();
        //plaintext = bytes;
        var str_block = this.str_block(plaintext, bit_size); //内容分段
        if (is_array(str_block)) {
            for (var i = 0, len = str_block.length, block = ''; i < len; i++) {
                block = str_block[i];
                if (delimiter) {
                    //分段内容加密，然后base64编码
                    enStr = util.encode64(pubKey.encrypt(block, 'RSAES-PKCS1-V1_5'));
                    cipherText.push(this.url_en64(enStr));
                    //console.log(cipherText);
                } else {
                    //panding OPENSSL_PKCS1_PADDING
                    cipherText.push(pubKey.encrypt(block, 'RSAES-PKCS1-V1_5'));
                }
            }
        }
        cipherText = forge.util.encode64(cipherText.join(delimiter));
        return is_url ? this.url_en64(cipherText) : cipherText;
    },
    /**
     * 私钥解密（长字符串解密）
     * @param {string} privateKey 私钥字符串
     * @param {string} cipherText 公钥加密的密文(base64)
     * @param {number} bit_size 密钥长度
     * @param {boolean} is_url 是否是url传递
     * @param {string} delimiter 分隔符
     */
    privateDecrypt: function (privateKey, cipherText, bit_size, is_url, delimiter) {
        var pki = forge.pki, util = forge.util, plaintext = [], de64Str;
        is_number(bit_size) || (bit_size = 1024);
        var block_size = ~~(bit_size / 8), slice;
        delimiter || (delimiter = "");
        (delimiter && /^[A-Za-z0-9_+\-\/]+$/.test(delimiter)) && (delimiter = ".");
        var priKey = pki.privateKeyFromPem(privateKey);
        cipherText = is_url ? util.decode64(this.url_de64(cipherText)) : util.decode64(cipherText); //base64解码
        if (delimiter && cipherText.search(delimiter) !== -1) {
            var list = cipherText.split(delimiter);
            for (var i = 0, len = list.length; i < len; i++) {
                //分段内容base64解码，然后解密
                de64Str = util.decode64(this.url_de64(list[i]));
                //console.log(de64Str,de64Str.length);
                //奶奶的，解码后的密文长度不等于 block_size，导致出错，以下处理可正常解密
                plaintext.push(priKey.decrypt(de64Str.slice(0, block_size), 'RSAES-PKCS1-V1_5')); //片段解密
            }
        } else {
            var data_len = cipherText.length;
            var num = ~~(data_len / block_size) + 1;
            (data_len % block_size === 0) && (num = num - 1);
            for (var i = 0, n = 1; i < num; i++, n++) {
                slice = cipherText.slice(i * block_size, block_size * n); //截取加密片段
                plaintext.push(priKey.decrypt(slice, 'RSAES-PKCS1-V1_5'));
            }
        }
        return plaintext.join("");
    },
    /**
     * 字符串分段，用于分段加密
     * @param {string} str 明文
     * @param {number} bit_size 密钥长度
     * @returns {*}
     */
    str_block: function (str, bit_size) {
        is_number(bit_size) || (bit_size = 1024);
        var block_size = ~~(bit_size / 8) - 11;
        if (y_string(str)) {
            var str_len = str.length;
            var len = ~~(str_len / block_size) + 1, r = [];
            (str_len % block_size === 0) && (len = len - 1);
            for (var i = 0, n = 1; i < len; i++, n++) {
                r.push(str.slice(i * block_size, block_size * n));
            }
            return r;
        }
        return false;
    },
    url_en64: function (encode64_str) {
        return String(encode64_str).replace(/[+]/g, "-").replace(/\//g, "_").replace(/=*$/, "");
    },
    url_de64: function (decode64_str) {
        return String(decode64_str).replace(/(-)/g, "+").replace(/_/g, "/");
    }
};
try {
    var rsa = new forge_rsa_help();
} catch (e) {

}